/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 *
 * $Id: PositionServer.hpp,v 1.12 2009-05-13 07:18:17 amaula Exp $
 *
 * \file
 * \brief MaCI - Position Server interface
 * \author Antti Maula <antti.maula@tkk.fi>
 *
 * \todo Add support for receiving unidirectional commands from Client.
 */
#ifndef _MACI_INTERFACE_POSITIONSERVER_HPP_
#define _MACI_INTERFACE_POSITIONSERVER_HPP_
#include "MaCI.hpp"
#include "PositionData.hpp"
#include "thread.hpp"
#include "sync.hpp"
#include <list>

// Forward declare gimi::GIMI
namespace gimi {
  class GIMI;
  class GIMIMessage;
}

namespace MaCI {
  namespace Position {

    /** MaCI - Position Server interface
     * 
     * This class contains the methods and types for providing
     * the Position service in the GIMnet.
     */
    class CPositionServer : public MaCI::CMaCI, 
                            private gim::CSync
    {
    public:
      /** Constructor.
       * 
       * Constructor of the PositionServer. This requires;
       * a pointer to Initialized and connected GIMI, minor
       * number of this interface (Used as GIMI minor number)
       *
       * @param[in] aMaCICtrlServerPtr Pointer to GIMI used for communication
       * @param[in] aInterfaceMinor Interface minor number. Usually
       * used to indicate the instance of devices of same type.
       * @param[in] aDescription User provided description about
       * service. This description will be appended after text
       * 'MaCI-PositionServer; ' in the GIMI service description
       * field.
       */
      CPositionServer(MaCICtrl::CMaCICtrlServer *aMaCICtrlServerPtr, 
                      const int aInterfaceMinor,
                      const std::string &aDescription = "");


      /** Destructor.
       */
      ~CPositionServer();
 

      /** Open device.
       *
       * Opens the device, basicly registers device to GIMI.
       *  
       * @return                Returns a value of type EMaCIError. 
       *                        
       * \see EMaCIError
       */
      MaCI::EMaCIError DoOpen(void);


      /** Close device.
       *
       * Closes the device. Closes all GIMI registrations and queues.
       *
       * @return                Returns a value of type EMaCIError.
       *
       * \see EMaCIError
       */
      MaCI::EMaCIError DoClose(void);
      


      /** Send a Position interface event. 
       * 
       * All fields present in the provided container will be transmitted.
       * The Event must atleast contain some position. (Empty events
       * will not be sent)
       *
       * \see CPositionData
       *
       * @param[in] aData       Reference to CPositionData element containing
       *                        atleast the position.
       * @return                'true' when the element was OK and was 
       *                        succesfully sent to GIMnet. (No guarantees
       *                        are made about reaching any subscriber).
       *                        'false' when the container was broken,
       *                        didn't contain correct elements or there
       *                        was some problem at the GIMnet layer.
       */
      bool SendPositionEvent(const CPositionData &aData);


      /** Wait for command from Client.
       *
       * This function waits for a Command to arrive from client, and returns it
       * in the provided reference to CPositionData.
       * The function guarantees that the data element contains a TCommand,
       * but the user must check whether all accompanying elements required for
       * the specified command exist.
       *
       * @param[out] aData      Reference to CPositionData to be filled.
       * @param[in] aTimeout_ms Time to wait for a command (milliseconds)
       * @return                'KMaCIOK'  when succesfully received
       *                        a new command. KMaCITimeout when operation
       *                        timed out before a command was received.
       *                        Other errors returned when appropriate.
       *                        (See the MaCI::EMaCIError for description)
       */
      EMaCIError WaitCommand(CPositionData &aData, 
                             const unsigned int aTimeout_ms);


    private:
      // Variables
      bool iServerActive; ///< Is the server active? - flag
      std::string iServiceDescription; ///< Service description field.
    };

  }
}


#endif //_MACI_INTERFACE_POSITIONSERVER_HPP_
